home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows 95 with MFC / Programming Windows 95 with MFC (Microsoft Programming Series)(097-0001465)(1996).iso / CODE / Chap10 / HexDump / HexView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-05  |  5.9 KB  |  202 lines

  1. //***********************************************************************
  2. //
  3. //  HexView.cpp
  4. //
  5. //***********************************************************************
  6.  
  7. #include <afxwin.h>
  8. #include <afxext.h>
  9. #include "HexDoc.h"
  10. #include "HexView.h"
  11.  
  12. #define PRINTMARGIN 2
  13.  
  14. IMPLEMENT_DYNCREATE (CHexView, CScrollView)
  15.  
  16. BEGIN_MESSAGE_MAP (CHexView, CScrollView)
  17.     ON_WM_CREATE ()
  18.     ON_COMMAND (ID_FILE_PRINT, CScrollView::OnFilePrint)
  19.     ON_COMMAND (ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
  20.     ON_COMMAND (ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
  21. END_MESSAGE_MAP ()
  22.  
  23. int CHexView::OnCreate (LPCREATESTRUCT lpcs)
  24. {
  25.     if (CScrollView::OnCreate (lpcs) == -1)
  26.         return -1;
  27.  
  28.     CClientDC dc (this);
  29.     int nHeight = -((dc.GetDeviceCaps (LOGPIXELSY) * 10) / 72);
  30.  
  31.     m_screenFont.CreateFont (nHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0,
  32.         DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
  33.         DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Courier New");
  34.  
  35.     TEXTMETRIC tm;
  36.     CFont* pOldFont = dc.SelectObject (&m_screenFont);
  37.     dc.GetTextMetrics (&tm);
  38.     m_cyScreen = tm.tmHeight + tm.tmExternalLeading;
  39.     dc.SelectObject (pOldFont);
  40.     return 0;
  41. }
  42.  
  43. void CHexView::OnInitialUpdate ()
  44. {
  45.     UINT nDocLength = GetDocument ()->GetDocumentLength ();
  46.     m_nLinesTotal = (nDocLength + 15) / 16;
  47.  
  48.     SetScrollSizes (MM_TEXT, CSize (0, m_nLinesTotal * m_cyScreen),
  49.         CSize (0, m_cyScreen * 10), CSize (0, m_cyScreen));
  50.     ScrollToPosition (CPoint (0, 0));
  51.  
  52.     CScrollView::OnInitialUpdate ();
  53. }
  54.  
  55. void CHexView::OnDraw (CDC* pDC)
  56. {
  57.     if (m_nLinesTotal != 0) {
  58.         CRect rect;
  59.         pDC->GetClipBox (&rect);
  60.  
  61.         UINT nStart = rect.top / m_cyScreen;
  62.         UINT nEnd = min (m_nLinesTotal - 1,
  63.             (rect.bottom + m_cyScreen - 1) / m_cyScreen);
  64.  
  65.         CString string;
  66.         CFont* pOldFont = pDC->SelectObject (&m_screenFont);
  67.  
  68.         for (UINT i=nStart; i<=nEnd; i++) {
  69.             FormatLine (i, string);
  70.             pDC->TextOut (2, (i * m_cyScreen) + 2, string);
  71.         }
  72.         pDC->SelectObject (pOldFont);
  73.     }
  74. }
  75.  
  76. BOOL CHexView::OnPreparePrinting (CPrintInfo* pInfo)
  77. {
  78.     return DoPreparePrinting (pInfo);
  79. }
  80.  
  81. void CHexView::OnBeginPrinting (CDC* pDC, CPrintInfo* pInfo)
  82. {
  83.     int nHeight = -((pDC->GetDeviceCaps (LOGPIXELSY) * 10) / 72);
  84.  
  85.     m_printerFont.CreateFont (nHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0,
  86.         DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
  87.         DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Courier New");
  88.  
  89.     TEXTMETRIC tm;
  90.     CFont* pOldFont = pDC->SelectObject (&m_printerFont);
  91.     pDC->GetTextMetrics (&tm);
  92.     m_cyPrinter = tm.tmHeight + tm.tmExternalLeading;
  93.     CSize size = pDC->GetTextExtent ("---------1---------2---------" \
  94.         "3---------4---------5---------6---------7---------8-", 81);
  95.     pDC->SelectObject (pOldFont);
  96.  
  97.     m_nLinesPerPage = (pDC->GetDeviceCaps (VERTRES) -
  98.         (m_cyPrinter * (3 + (2 * PRINTMARGIN)))) / m_cyPrinter;
  99.     UINT nMaxPage = max (1, (m_nLinesTotal + (m_nLinesPerPage - 1)) /
  100.         m_nLinesPerPage);
  101.     pInfo->SetMaxPage (nMaxPage);
  102.  
  103.     m_cxOffset = (pDC->GetDeviceCaps (HORZRES) - size.cx) / 2;
  104.     m_cxWidth = size.cx;
  105. }
  106.  
  107. void CHexView::OnPrint (CDC* pDC, CPrintInfo* pInfo)
  108. {
  109.     PrintPageHeader (pDC, pInfo->m_nCurPage);
  110.     PrintPage (pDC, pInfo->m_nCurPage);
  111. }
  112.  
  113. void CHexView::OnEndPrinting (CDC* pDC, CPrintInfo* pInfo)
  114. {
  115.     m_printerFont.DeleteObject ();
  116. }
  117.  
  118. void CHexView::FormatLine (UINT nLine, CString& string)
  119. {
  120.     BYTE b[17];
  121.     ::FillMemory (b, 16, 32);
  122.     UINT nCount = GetDocument ()->GetBytes (nLine * 16, 16, b);
  123.  
  124.     string.Format ("%0.8X    %0.2X %0.2X %0.2X %0.2X %0.2X %0.2X " \
  125.         "%0.2X %0.2X - %0.2X %0.2X %0.2X %0.2X %0.2X %0.2X %0.2X " \
  126.         "%0.2X    ", nLine * 16,
  127.         b[0], b[1],  b[2],  b[3],  b[4],  b[5],  b[6],  b[7],
  128.         b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]);
  129.  
  130.     for (UINT i=0; i<nCount; i++) {
  131.         if (!::IsCharAlphaNumeric (b[i]))
  132.             b[i] = 0x2E;
  133.     }
  134.  
  135.     b[nCount] = 0;
  136.     string += b;
  137.  
  138.     if (nCount < 16) {
  139.         UINT pos1 = 59;
  140.         UINT pos2 = 60;
  141.         UINT j = 16 - nCount;
  142.  
  143.         for (i=0; i<j; i++) {
  144.             string.SetAt (pos1, ' ');
  145.             string.SetAt (pos2, ' ');
  146.             pos1 -= 3;
  147.             pos2 -= 3;
  148.             if (pos1 == 35) {
  149.                 string.SetAt (35, ' ');
  150.                 string.SetAt (36, ' ');
  151.                 pos1 = 33;
  152.                 pos2 = 34;
  153.             }
  154.         }
  155.     }
  156. }
  157.  
  158. void CHexView::PrintPageHeader (CDC* pDC, UINT nPageNumber)
  159. {
  160.     CString strHeader = GetDocument ()->GetPathName ();
  161.     if (strHeader.GetLength () > 68)
  162.         strHeader = GetDocument ()->GetTitle ();
  163.  
  164.     CString strPageNumber;
  165.     strPageNumber.Format ("Page %d", nPageNumber);
  166.  
  167.     UINT nSpaces = 81 - strPageNumber.GetLength () -
  168.         strHeader.GetLength ();
  169.     for (UINT i=0; i<nSpaces; i++)
  170.         strHeader += ' ';
  171.     strHeader += strPageNumber;
  172.  
  173.     UINT y = m_cyPrinter * PRINTMARGIN;
  174.     CFont* pOldFont = pDC->SelectObject (&m_printerFont);
  175.     pDC->TextOut (m_cxOffset, y, strHeader);
  176.  
  177.     y += (m_cyPrinter * 3) / 2;
  178.     pDC->MoveTo (m_cxOffset, y);
  179.     pDC->LineTo (m_cxOffset + m_cxWidth, y);
  180.  
  181.     pDC->SelectObject (pOldFont);
  182. }
  183.  
  184. void CHexView::PrintPage (CDC* pDC, UINT nPageNumber)
  185. {
  186.     if (m_nLinesTotal != 0) {
  187.         UINT nStart = (nPageNumber - 1) * m_nLinesPerPage;
  188.         UINT nEnd = min (m_nLinesTotal - 1, nStart + m_nLinesPerPage - 1);
  189.  
  190.         CString string;
  191.         CFont* pOldFont = pDC->SelectObject (&m_printerFont);
  192.  
  193.         UINT y;
  194.         for (UINT i=nStart; i<=nEnd; i++) {
  195.             FormatLine (i, string);
  196.             y = ((i - nStart) + PRINTMARGIN + 3) * m_cyPrinter;
  197.             pDC->TextOut (m_cxOffset, y, string);
  198.         }
  199.         pDC->SelectObject (pOldFont);
  200.     }
  201. }
  202.